"use strict";
var __importDefault = (this && this.__importDefault) || function (mod) {
    return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
const fs_1 = __importDefault(require("fs"));
const axios_1 = __importDefault(require("axios"));
const path_1 = __importDefault(require("path"));
const fs_promise_1 = __importDefault(require("fs-promise"));
const koa_router_1 = __importDefault(require("koa-router"));
const ContentTypeTool_1 = __importDefault(require("../lib/ContentTypeTool"));
const awaitWrap_1 = __importDefault(require("../lib/awaitWrap"));
const configTool_1 = __importDefault(require("../com/configTool"));
const index_1 = __importDefault(require("../lib/FSTool/index"));
const readFromDB_1 = __importDefault(require("../lib/GISServer/Util/readFromDB"));
const readFromNet_1 = __importDefault(require("../lib/GISServer/Util/readFromNet"));
const crypto_1 = __importDefault(require("crypto"));
const saveToDB_1 = __importDefault(require("../lib/GISServer/Util/saveToDB"));
const initDB_1 = __importDefault(require("../lib/GISServer/Util/initDB"));
const MapboxTile_1 = __importDefault(require("../lib/GISServer/MapboxTile/MapboxTile"));
const CesiumTerrain_1 = __importDefault(require("../lib/GISServer/CesiumTerrain/CesiumTerrain"));
const ProxyRoutes = new koa_router_1.default({ prefix: '/proxyServer' });
function getRequestParams(ctx) {
    const protocol = ctx.params.protocol === 'http' ? 'http://' : 'https://';
    const ip = ctx.params.ip;
    const port = ctx.params.port;
    const relativeUrl = ctx.params.url;
    let originalUrl = `${protocol}${ip}:${port}/${relativeUrl}`;
    const originalParam = ctx.request.query;
    if (Object.keys(originalParam).length !== 0) {
        originalUrl += '?' + Object.keys(originalParam).map(key => {
            return `${key}=${originalParam[key]}`;
        }).join('&');
    }
    return { protocol, ip, port, relativeUrl, originalUrl };
}
ProxyRoutes
    .get('/no-cache/:protocol/:ip/:port/:url(.*)', async (ctx) => {
    const { originalUrl } = getRequestParams(ctx);
    if (originalUrl) {
        let [err, res] = await (0, awaitWrap_1.default)(axios_1.default.get(originalUrl, { responseType: 'arraybuffer' }));
        if (err) {
            ctx.status = 422;
            ctx.body = err;
        }
        else {
            for (const resKey in res.headers) {
                ctx.set(resKey, res.headers[resKey]);
            }
            ctx.body = res.data;
        }
    }
})
    .get('/auto-cache/:protocol/:ip/:port/:url(.*)', async (ctx) => {
    const { ip, port, relativeUrl, originalUrl } = getRequestParams(ctx);
    let fileSavePath = path_1.default.join(configTool_1.default.appBasePath, 'temp/fileOut', `${ctx.params.protocol}/${ip}/${port}/${relativeUrl}`);
    let fileDir = path_1.default.dirname(fileSavePath);
    if (originalUrl) {
        let [err, res] = await index_1.default.readFileAsync(fileSavePath);
        if (res) {
            let contentType = ContentTypeTool_1.default.getContentType(fileSavePath);
            ctx.set('Content-Type', contentType);
            ctx.body = res;
        }
        if (!res) {
            [err, res] = await (0, awaitWrap_1.default)(axios_1.default.get(originalUrl, { responseType: 'arraybuffer' }));
            if (err) {
                ctx.status = 422;
                ctx.body = err;
            }
            else {
                for (const resKey in res.headers) {
                    ctx.set(resKey, res.headers[resKey]);
                }
                ctx.body = res.data;
                if (configTool_1.default.preservableONFile()) {
                    if (!path_1.default.extname(fileSavePath)) {
                        fileSavePath += ContentTypeTool_1.default.getExt(res.headers['content-type']);
                    }
                    await fs_promise_1.default.ensureDir(fileDir);
                    fs_1.default.writeFileSync(fileSavePath, res.data);
                }
            }
        }
    }
})
    .get('/wall-Proxy/:protocol/:ip/:port/:url(.*)', async (ctx) => {
    const { ip, port, relativeUrl, originalUrl } = getRequestParams(ctx);
    const fileSavePath = path_1.default.join(configTool_1.default.appBasePath, 'temp/fileOut', `${ctx.params.protocol}/${ip}/${port}/${relativeUrl}`);
    const dbPath = '\\' + relativeUrl.replaceAll('/', '\\');
    if (originalUrl) {
        let err, buffer, dataSource;
        await (0, initDB_1.default)(ip);
        [err, buffer, dataSource] = await (0, readFromDB_1.default)({ DBName: ip, relativePath: dbPath });
        [err, buffer, dataSource] = await (0, readFromNet_1.default)({
            url: originalUrl, headers: {}, err, buffer, dataSource, option: {
                proxy: {
                    protocol: 'http',
                    host: '127.0.0.1',
                    port: 7890
                }
            }
        });
        if (buffer) {
            let contentType = ContentTypeTool_1.default.getContentType(fileSavePath);
            ctx.set('Content-Type', contentType);
            ctx.body = buffer;
            const md5Str = crypto_1.default.createHash('md5').update(buffer).digest('hex');
            if (md5Str) {
                (0, saveToDB_1.default)({ DBName: ip, relativePath: dbPath, buffer }).then();
            }
        }
        else {
            ctx.status = 422;
            ctx.set('Content-Type', 'application/json;charset=utf-8');
            ctx.body = err;
            console.warn('代理 翻墙路径失败');
        }
    }
})
    .get('/api.mapbox.com/v4/mapbox.satellite/:z/:x/:y.webp', async (ctx) => {
    let { z, x, y } = ctx.params;
    let [err, buffer] = await MapboxTile_1.default.getSatelliteFileBuffer(z, x, y);
    if (buffer) {
        ctx.set('Content-Type', 'image/jpeg');
        ctx.body = buffer;
    }
    else {
        ctx.status = 422;
        ctx.set('Content-Type', 'application/json;charset=utf-8');
        ctx.body = err;
        console.log('代理 MapBoxTile 瓦片失败', z, x, y);
    }
})
    .get('/api.mapbox.com/v4/mapbox.terrain-rgb/:z/:x/:y.png', async (ctx) => {
    let { z, x, y } = ctx.params;
    let [err, buffer] = await MapboxTile_1.default.getTerrainRGBFileBuffer(z, x, y);
    if (buffer) {
        ctx.set('Content-Type', 'image/png');
        ctx.body = buffer;
    }
    else {
        ctx.status = 422;
        ctx.set('Content-Type', 'application/json;charset=utf-8');
        ctx.body = err;
        console.log('代理 MapBoxTile 瓦片失败', z, x, y);
    }
})
    .get('/assets.cesium.com/1/:url(.*)', async (ctx) => {
    await CesiumTerrain_1.default.init();
    console.log(await CesiumTerrain_1.default.ionAuthority());
    const url = ctx.params.url;
    let fileSavePath = path_1.default.join(configTool_1.default.appBasePath, 'temp/fileOut/assets.cesium.com/1/', url);
    let [err, buffer] = await index_1.default.readFileAsync(fileSavePath);
    if (err) {
        [err, buffer] = await CesiumTerrain_1.default.getFileBuffer(url);
    }
    if (buffer) {
        ctx.body = buffer;
    }
    else {
        ctx.status = 422;
        ctx.body = err;
        console.log(`代理 Cesium 官方地形数据失败，${ctx.url}`);
    }
});
exports.default = ProxyRoutes;
